package org.dromara.crawler.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mongodb.client.gridfs.model.GridFSFile;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.crawler.domain.bo.KnowledgeTargetBo;
import org.dromara.crawler.mongo.mongodomain.KnowledgeEvent;
import org.dromara.crawler.mongo.mongodomain.KnowledgeTarget;
import org.dromara.crawler.mongo.mongoservice.KnowledgeEventService;
import org.dromara.crawler.mongo.mongoservice.KnowledgeTargetService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;
import java.util.*;

/**
 * 知识目标管理接口
 */
@Slf4j
@RestController
@RequestMapping("/knowledgeEvent")
public class KnowledgeTargetController {

    @Autowired
    private KnowledgeEventService knowledgeEventService;
    @Autowired
    private KnowledgeTargetService knowledgeTargetService;

    private GridFsTemplate knowledgeTargetGridFsTemplate;

    public KnowledgeTargetController(@Qualifier("knowledgeTargetGridFsTemplate") GridFsTemplate knowledgeTargetGridFsTemplate) {
        this.knowledgeTargetGridFsTemplate = knowledgeTargetGridFsTemplate;
    }


    /**
     * event查询全部
     */
    @GetMapping("/getAll")
    public R<List<KnowledgeEvent>> getEventAll() {
        try {
            return R.ok(knowledgeEventService.getEventAll());
        } catch (Exception e) {
            log.error("获取失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * event根据id查询
     */
    @GetMapping("/getById")
    public R<KnowledgeEvent> getEventById(@RequestParam String id) {
        try {
            return R.ok(knowledgeEventService.queryEventById(id));
        } catch (Exception e) {
            log.error("查询失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 目标知识查询全部
     */
    @GetMapping("/getTargetAll")
    public R<List<KnowledgeTarget>> getTargetAll() {
        try {
            return R.ok(knowledgeTargetService.getAll());
        } catch (Exception e) {
            log.error("获取失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 目标知识根据id查询
     */
    @GetMapping("/getTargetById")
    public R<KnowledgeTarget> getTargetById(@RequestParam String id) {
        try {
            return R.ok(knowledgeTargetService.queryById(id));
        } catch (Exception e) {
            log.error("查询失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 目标知识条件查询
     */
    @GetMapping("/queryTargetByCondition")
    public R<List<KnowledgeTarget>> queryTargetByCondition(KnowledgeTargetBo knowledgeTargetBo) {
        try {
            List<KnowledgeTarget> targets = knowledgeTargetService.queryByCondition(knowledgeTargetBo);
            return R.ok(targets);
        } catch (Exception e) {
            log.error("根据条件查询失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 目标知识分页查询
     */
    @GetMapping("/queryTargetByPage")
    public R<Page<KnowledgeTarget>> queryByPage(KnowledgeTargetBo knowledgeTargetBo,
                                                @RequestParam(defaultValue = "1") Integer pageNum,
                                                @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            PageQuery pageQuery = new PageQuery(pageSize, pageNum);
            return R.ok(knowledgeTargetService.queryByPage(knowledgeTargetBo, pageQuery));
        } catch (Exception e) {
            log.error("分页查询目标知识失败，原因：" + e.getMessage(), e);
            return R.fail(e.getMessage());
        }
    }

    /**
     * 新增知识目标
     */
    @PostMapping("/add")
    public R<String> add(@RequestBody KnowledgeTarget knowledgeTarget) {
        try {
            boolean result = knowledgeTargetService.add(knowledgeTarget);
            if (result) {
                return R.ok("新增成功");
            } else {
                return R.fail("新增失败");
            }
        } catch (Exception e) {
            log.error("新增失败，原因：" + e.getMessage(), e);
            return R.fail(e.getMessage());
        }
    }


    /**
     * 删除知识目标
     */
    @DeleteMapping("/deleteByTargetId")
    public R<String> deleteByTargetId(@RequestParam String targetId) {
        try {
            boolean result = knowledgeTargetService.deleteByTargetId(targetId);
            if (result) {
                return R.ok("删除成功");
            } else {
                return R.fail("删除失败，未找到指定的目标知识");
            }
        } catch (Exception e) {
            log.error("删除失败，原因：" + e.getMessage(), e);
            return R.fail(e.getMessage());
        }
    }

    /**
     * 更新知识目标
     */
    @PutMapping("/update")
    public R<String> update(@RequestBody KnowledgeTarget knowledgeTarget) {
        try {
            boolean result = knowledgeTargetService.updateByTargetId(knowledgeTarget);
            if (result) {
                return R.ok("更新成功");
            } else {
                return R.fail("更新失败，未找到指定的目标知识");
            }
        } catch (Exception e) {
            log.error("更新失败，原因：" + e.getMessage(), e);
            return R.fail(e.getMessage());
        }
    }
    /**
     * 事件知识分页查询
     */
    @GetMapping("/queryKnowledgeEventByPage")
    public R<Page<KnowledgeEvent>> queryKnowledgeEventByPage(KnowledgeTargetBo knowledgeTargetBo,
                                                             @RequestParam(defaultValue = "1") Integer pageNum,
                                                             @RequestParam(defaultValue = "10") Integer pageSize) {
        PageQuery pageQuery = new PageQuery(pageSize, pageNum);
        return R.ok(knowledgeEventService.queryByEventPage(knowledgeTargetBo, pageQuery));
    }

    /**
     * 事件知识条件查询
     */
    @GetMapping("/queryEventByCondition")
    public R<List<KnowledgeEvent>> queryEventByCondition(KnowledgeTargetBo knowledgeTargetBo) {
        try {
            List<KnowledgeEvent> events = knowledgeEventService.queryEvent(knowledgeTargetBo);
            return R.ok(events);
        } catch (Exception e) {
            log.error("根据条件查询失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }


    /**
     * 知识库分类统计
     */
    @GetMapping("/getPredictedCategoryStats")
    public R<List<Map<String, String>>> getPredictedCategoryStats() {
        try {
            // 获取KnowledgeEvent的统计结果
            Map<String, Long> eventStats = knowledgeEventService.getPredictedCategoryStats();
            // 获取KnowledgeTarget的统计结果
            Map<String, Long> targetStats = knowledgeTargetService.getTargetEventFirstLevelStats();

            // 合并两个统计结果
            Map<String, Long> mergedStats = new HashMap<>();
            List<String> categories = Arrays.asList("台海政治", "台海经济", "台海军事");
            for (String category : categories) {
                long eventCount = eventStats.getOrDefault(category, 0L);
                long targetCount = targetStats.getOrDefault(category, 0L);
                mergedStats.put(category, eventCount + targetCount);
            }

            List<Map<String, String>> result = new ArrayList<>();
            for (Map.Entry<String, Long> entry : mergedStats.entrySet()) {
                Map<String, String> item = new HashMap<>();
                item.put("name", entry.getKey());
                item.put("value", String.valueOf(entry.getValue()));
                result.add(item);
            }

            return R.ok(result);
        } catch (Exception e) {
            log.error("获取统计数据失败，原因：" + e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 目标知识库上传图片
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public R<String> uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            throw new IllegalArgumentException("No file uploaded");
        }
        // 生成文件的内容类型
        String contentType = file.getContentType();
        String fileName = file.getOriginalFilename();
        // 将文件存储到GridFS中
        try (InputStream inputStream = file.getInputStream()) {
            return R.ok("上传成功",knowledgeTargetGridFsTemplate.store(inputStream, fileName, contentType).toString());
        }
    }

    /**
     * 查询目标知识的图片接口
     */
    @GetMapping("/getKnowledgeTargetImage")
    public void getKnowledgeTargetImage(@RequestParam String imageId, HttpServletResponse response) {
        getOutputStream(imageId, response, knowledgeTargetGridFsTemplate);
    }

    private void getOutputStream(String imageId, HttpServletResponse response, GridFsTemplate gridFsTemplate) {
        try {
            // 查询 GridFS 文件
            GridFSFile file = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(new ObjectId(imageId))));
            if (file == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                response.setContentType("text/plain");
                response.getWriter().write("Image not found.");
                return;
            }
            // 获取文件资源
            GridFsResource resource = gridFsTemplate.getResource(file);
            // 尝试从 metadata 获取 contentType，否则根据文件名后缀推断
            String contentType = null;
            if (file.getMetadata() != null && file.getMetadata().get("_contentType") != null) {
                contentType = file.getMetadata().get("_contentType").toString();
            } else {
                contentType = URLConnection.guessContentTypeFromName(resource.getFilename());
            }
            if (contentType == null) {
                contentType = "application/octet-stream"; // fallback
            }

            // 设置响应头
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
            // 输出图片内容
            try (InputStream is = resource.getInputStream(); OutputStream os = response.getOutputStream()) {
                StreamUtils.copy(is, os); // 更简洁
            }
        } catch (Exception e) {
            // 统一错误处理（返回状态码 + 消息）
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("text/plain");
                response.getWriter().write("读取图片异常：" + e.getMessage());
                e.printStackTrace();
            } catch (IOException ioException) {
                // 忽略
            }
        }
    }


}
